package pl.edu.agh.admin.core;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import pl.edu.agh.admin.api.CronParameter;
import pl.edu.agh.admin.api.CronTabManager;
import pl.edu.agh.admin.api.PermissionDeniedException;
import pl.edu.agh.admin.api.Task;
import pl.edu.agh.admin.api.User;

public class CronTabManagerImpl implements CronTabManager {

	private String cmd = "cat /etc/passwd";// | grep /bin/bash | cut -d: -f1";
	private Map<User, List<Task>> user2task;
	private String logged = null;
	private String cronTabDir = "/var/spool/cron/crontabs/";
	
	public CronTabManagerImpl(){
		user2task = new HashMap<User, List<Task>>();
		logged = System.getProperty("user.name");
		loadCronTabs();
	}
	
	@Override
	public Collection<User> getUseres() {
		return user2task.keySet();
	}

	@Override
	public Collection<Task> getAllTasks() {
		Collection<Task> all = new HashSet<Task>();
		for(User u : user2task.keySet()){
			all.addAll(user2task.get(u));
		}
		return all;
	}

	@Override
	public Collection<Task> getUserTasks(User user) {
		return user2task.get(user);
	}

	@Override
	public Task createTask(User user, String cron, String command) throws PermissionDeniedException{
		if(user.getName().equals(logged) || logged.equals("root")){
			return createTask(user, cron + " " + command);
		}else{
			throw new PermissionDeniedException("Can't create Task!");
		}
	}
	
	private Task createTask(User user, String cronLine){

			Map<CronParameter, String> params = null;
			List<Task> list = null;
			if(user2task.containsKey(user)){
				list = user2task.get(user);			
			}else{
				list = new LinkedList<Task>();
				user2task.put(user, list);
			}
			if(!list.isEmpty()){
				params = list.get(0).getParameters();
			}else{
				params = new HashMap<CronParameter, String>();
			}
			Task task = new TaskImpl(cronLine, user, params);
			list.add(task);
			return task;
	}

	@Override
	public void deleteTask(Task task) throws PermissionDeniedException {
		User user = task.getUser();
		if(user.getName().equals(logged) || logged.equals("root")){
			user2task.get(user).remove(task);
		}else{
			throw new PermissionDeniedException("Can't delete Task!");
		}
		
	}
	
	@Override
	public void save() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void load() {
		loadCronTabs();
	}
	
	private void loadCronTabs() {
		for(String name : loadSystemUsers()){
			User u = new UserImpl(name);
			user2task.put(u, loadUserTask(u));
		}
	}

	private  List<String> loadSystemUsers(){
		List<String> userNames = new LinkedList<String>();
		userNames.add("root");
		try{
			Process proc = Runtime.getRuntime().exec(cmd);
			proc.waitFor();
			BufferedReader in = new BufferedReader(new InputStreamReader(proc.getInputStream()));
			String readLine = in.readLine();
			
			while(readLine != null){
				String[] split = readLine.split(":");
				int nr = Integer.parseInt(split[2]);
				if(nr > 999 && nr < 9999){
					String name = split[0];
					userNames.add(name);
					System.out.println("user: " + name);
				}
				readLine = in.readLine();
			}
		}catch (Exception e) {
			e.printStackTrace();
		}
		return userNames;
	}
	
	private List<Task> loadUserTask(User u){
		List<Task> tasks = new LinkedList<Task>();
		File file = new File(cronTabDir + u.getName());
		try {
			Map<CronParameter, String> params = new HashMap<CronParameter, String>();
			BufferedReader in = new BufferedReader(new FileReader(file));
			String line = in.readLine();
			while(line != null){
				if(!line.startsWith("#")){
					tasks.add(new TaskImpl(line, u, params));
				}
				line = in.readLine();
			}
		} catch (FileNotFoundException e) {
			System.out.println(u.getName() + " has no crontab");
		} catch (IOException e) {
			e.printStackTrace();
		}
		return tasks;
	}


}
